#!/user/bin/env python
# -*- coding: utf-8 -*-
''' 
Author: Sjy
LastEditTime: 2024-09-04 09:57:28
Description: 封装 针对pyqtribbon 的相关函数扩展 便于通过配置的方式生成菜单  TODO:待完成
需求如下：
1. 菜单通过json配置，支持定制模式，这个不适合因为存在响应函数，因此应该提供类继承和重写的方式而不是通过json方式处理
2. 要区分前后处理菜单的不同
3. 菜单可能会动态变化，因此要支持动态加载卸载

需求重新整理如下：
1. 菜单分层
    1. 全局菜单，提供通用功能，可配置显示隐藏，不同的程序都会加载
    2. 应用菜单  一般会分为前处理程序和后处理程序，不同应用的菜单可能不同
    3. 工程菜单  不同的工程可能提供不同的应用菜单，切换不同工程时工程菜单也要随着发生改变
2. 加载要由顺序 
3. 考虑工程菜单如何动态的加载和卸载


pyqtribbon 常用接口


pannel 对象
addLargeButton(
    text: str = None, 
    icon: QIcon = None, 
    showText: bool = True, 
    slot: Callable = None, 
    shortcut: Key | QKeySequence | QtCore.QKeyCombination | StandardKey | str | int = None, 
    tooltip: str = None, 
    statusTip: str = None, 
    checkable: bool = False, *, 
    rowSpan: RibbonButtonStyle = RibbonButtonStyle.Large, **kwargs
)   → RibbonToolButton[source]

'''

__all__= []
import types

from PyQt5 import QtWidgets, QtGui

try:
    from .utils import is_fun, is_list
except:
    from utils import is_fun, is_list

def add_submenu(qmenu, menu):
    """添加子菜单"""
    if qmenu == None or menu == None:
        """任何一项不存在都主动退出"""
        return
    
    for item in menu:
        if "menu" in item:
            """存在子菜单"""
            subMenu = qmenu.addMenu(QtGui.QIcon(item.get("icon")), item.get("title"))
            add_submenu(subMenu, item.get("menu"))
        elif "title" in item:
            """正常菜单项必须包含title"""
            menuItem = qmenu.addAction(QtGui.QIcon(item.get("icon")), item.get("title"))
            action = item.get("action")
            if is_fun(action)  :
                menuItem.triggered.connect(action)
        else:
            """添加分隔符"""
            qmenu.addSeparator()

def add_menu_items(qmenu, menu):
    """添加菜单项，注意会返回按钮的默认行为函数"""
    defaultAction = None
    for item in menu:
        if "menu" in item:
            subMenu = qmenu.addMenu(QtGui.QIcon(item.get("icon")), item.get("title"))
            add_submenu(subMenu, item.get("menu"))
        elif "title" in item:
            menuItem = qmenu.addAction(QtGui.QIcon(item.get("icon")), item.get("title"))
            action = item.get("action")
            if is_fun(action) :
                menuItem.triggered.connect(action)
            if item.get("defaultAction"):
                defaultAction = menuItem
        else:
            qmenu.addSeparator()
    return defaultAction

def btn_set_menu(qpushbutton, params:dict={}):
    """按钮设置菜单"""
    qmenu = QtWidgets.QMenu()
    defaultAction = None
    menu = params.get("menu", None)
    if isinstance(menu, list):
        defaultAction = add_menu_items(qmenu, menu)
    qpushbutton.setMenu(qmenu)
    popupMode = params.get("popupMode", "MenuButtonPopup")
    if popupMode == "MenuButtonPopup":
        popupMode = QtWidgets.QToolButton.MenuButtonPopup
    elif popupMode == "InstantPopup":
        popupMode = QtWidgets.QToolButton.InstantPopup
    qpushbutton.setPopupMode(popupMode)
    defaultAction and qpushbutton.setDefaultAction(defaultAction)
    return qmenu
def add_menu(btn, params:dict={}):
    """添加菜单，两种方式，如果传入的是函数则调用由函数本身创建，如果是list则自动创建"""
    qmenu = None 
    menu = params.get("menu", None)
    if is_fun(menu):
        qmenu = menu(btn, params)
    elif is_list(menu):
        qmenu = btn_set_menu(btn, params)
def add_toggle_btn(pannel, params:dict={}):
    pass

def add_large_btn(pannel, params:dict={}):
    """添加大按钮"""
    title = params.get("title", "")
    icon = params.get("icon", None)
    showText = params.get("showText", True)
    slot = params.get("slot", None)
    shortcut = params.get("shortcut", None)
    tooltip = params.get("tooltip", None)
    statusTip = params.get("statusTip", None)
    checkable = params.get("checkable", False) # 值为 True 则 addLargeToggleButton
    action = params.get("action", None)
    btn = pannel.addLargeButton(title, icon, showText=showText, slot=slot, shortcut=shortcut, tooltip=tooltip, statusTip=statusTip, checkable=checkable)
    if isinstance(action, types.FunctionType):
        btn.clicked.connect(action)
    menu = params.get("menu", None)
    if menu:
        add_menu(btn, menu)

def load_categories(categories):
    pass
    # ribbonbar = gl.get_value("ribbonbar")
    # for category in categories:
    #     # bar = self._ribbonbar._categories.get(category.get("title"))
    #     # if not bar:
    #     #     bar = self._ribbonbar.addCategory(self.translate(category.get("title"))) 
    #     for pannel in category.get("pannels") or []:
    #         self.load_pannel(bar, pannel)